package com.lgy.controller;

import cn.hutool.json.JSONUtil;
import com.lgy.config.EsConfig;
import com.lgy.utils.EsUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

@RestController
@Slf4j
public class TestController {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * curl http://127.0.0.1:8081/es/testEsDataExist?day=2023-02-21
     * 判斷es中的数据是否达标
     * @param day
     * @return
     */
    @RequestMapping("/testEsDataExist")
    public Object testEsDataExist(String day) {
        String sql = "SELECT DISTINCT watch_member_id FROM live_user_watch_report_log20230221 WHERE report_time = '" + day+ "'";
        List<Map<String, Object>> data = jdbcTemplate.queryForList(sql);
        List<Long> totalRightUser = new ArrayList<>();
        for(Map<String, Object> map : data) {
            Long watchMemberId = (Long) map.get("watch_member_id");
            totalRightUser.add(watchMemberId);
        }

        List<Map<String, Object>> allEsData = findAllEsData(day);
        Set<Long> watchMemberIdEs = new HashSet<>();
        for(Map<String, Object> es : allEsData) {
            Long esWatchMemberId = Long.valueOf((Integer) es.get("watchMemberId"));
            //判断es中数据有没有达标
            if(totalRightUser.contains(esWatchMemberId)) {
                //达标
            } else {
                watchMemberIdEs.add(esWatchMemberId);
            }
        }
        if(!watchMemberIdEs.isEmpty()) {
            System.out.println(watchMemberIdEs);
            //修改为不达标
            //根据watchMemberId进行修改
            /*for(Long esWatchmemberId : watchMemberIdEs) {
                System.out.println(esWatchmemberId + "--------------->");
                updateByWatchMemberId(esWatchmemberId, day);
            }*/
        } else {
            System.out.println("无-------------》");
        }
        return "执行结束! watchMemberId:" + watchMemberIdEs.size();
    }


    public static void updateByWatchMemberId(Long watchMemberId, String dayTime) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(dayTime).format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").lte(dayTime).format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.termQuery("flag", 1));
        boolQueryBuilder.must(QueryBuilders.termQuery("watchMemberId", watchMemberId));
        SearchHit[] hits;
        SearchRequest request = new SearchRequest("live_dept_panel");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);//查询参数
        sourceBuilder.size(30000);
        request.source(sourceBuilder);
        try {
            hits = EsConfig.getEsInstance().search(request, RequestOptions.DEFAULT).getHits().getHits();
            for(SearchHit hit : hits) {
                Map<String,Object> temp = hit.getSourceAsMap();
                temp.put("flag", 0);
                EsUtil.updateDoc(hit.getId(), "live_dept_panel", JSONUtil.toJsonStr(temp));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<Map<String,Object>> findAllEsData(String dayTime) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(dayTime).format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").lte(dayTime).format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.termQuery("flag", 1));
        SearchHit[] hits;
        SearchRequest request = new SearchRequest("live_dept_panel");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);//查询参数
        sourceBuilder.size(30000);
        request.source(sourceBuilder);
        try {
            hits = EsConfig.getEsInstance().search(request, RequestOptions.DEFAULT).getHits().getHits();
            List<Map<String,Object>> map = new ArrayList<>();
            for(SearchHit hit : hits) {
                Map<String,Object> temp = hit.getSourceAsMap();
                temp.put("_id", hit.getId());
                map.add(temp);
            }
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<Long> check(List<Long> watchMemberIds, String dayTime) {
        List<Long> checkData = new ArrayList<>();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(dayTime).format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").lte(dayTime).format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.termQuery("flag", 1));
        //ES的in查询
        boolQueryBuilder.must(QueryBuilders.termsQuery("watchMemberId", watchMemberIds));

        SearchRequest request = new SearchRequest("live_dept_panel");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);//查询参数
        sourceBuilder.size(10000);
        request.source(sourceBuilder);
        try {
            SearchHit[] hits = EsConfig.getEsInstance().search(request, RequestOptions.DEFAULT).getHits().getHits();
            for(SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                Long esWatchMemberId = Long.valueOf((Integer) sourceAsMap.get("watchMemberId"));
                checkData.add(esWatchMemberId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return checkData;
    }
   /* @RequestMapping("/testInsert")
    public Object testInsert(String day) throws IOException {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //boolQueryBuilder.must(QueryBuilders.termQuery("id", "4A-aHYEBAjFB-1kET5Jg"));
        //范围匹配
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").gte("2022-06-17").format("yyyy-MM-dd"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").lte("2022-06-17").format("yyyy-MM-dd"));
        //boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(day + " 07:00:00").lte(day + " 19:00:00"));
        boolQueryBuilder.must(QueryBuilders.termQuery("flag", 1));
        //ES的in查询
        List<Integer> regions = new ArrayList<>();
        regions.add(2);
        boolQueryBuilder.must(QueryBuilders.termsQuery("regionId", regions));

        SearchHit[] hits;
        SearchRequest request = new SearchRequest("live_dept_panel");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);//查询参数
        sourceBuilder.size(1000000);
        request.source(sourceBuilder);
        try {
            hits = EsConfig.getEsInstance().search(request, RequestOptions.DEFAULT).getHits().getHits();
            ThreadUtil.execAsync(() -> {
                int i = 0;
                List<Object[]> list = new ArrayList<>();
                for(SearchHit hit : hits) {
                    Map<String,Object> map = hit.getSourceAsMap();
                    //String sql = "INSERT INTO online_panel_data VALUES(?,?,?,?,?,?,?,?)";
                    //jdbcTemplate.update(sql, new Object[]{hit.getId(),map.get("watchMemberId"),map.get("imei"),map.get("liveId"),map.get("num"),map.get("flag"),map.get("regionId"),map.get("createTime")});
                    //strings[i] = "INSERT INTO online_panel_data VALUES('"+ hit.getId() + "','"+map.get("watchMemberId")+"','"+map.get("imei")+"','"+map.get("liveId")+"','"+map.get("num")+"','"+map.get("flag")+"','"+map.get("regionId")+"', '"+map.get("createTime")+"')";
                    Object[] obj = new Object[8];
                    obj[0] = hit.getId();
                    obj[1] = map.get("watchMemberId");
                    String imei = (String) map.get("imei");
                    obj[2] = imei.length() > 255 ? imei.substring(0,128) + "20220611":imei;
                    obj[3] = map.get("liveId");
                    obj[4] = map.get("num");
                    obj[5] = map.get("flag");
                    obj[6] = map.get("regionId");
                    obj[7] = map.get("createTime");
                    list.add(obj);
                    //i++;
                    //System.out.println(hit.getId() + "---------->" + i);
                    //修改
                    //Map<String,Object> map = hit.getSourceAsMap();
                    //map.put("flag",0);
                    //EsUtil.updateDoc(hit.getId(),"live_dept_panel",JSONUtil.parseObj(map).toString());

                }

                List<List<Object[]>> lists = splitListByCount(list, 1000);
                String sql = "INSERT INTO online_panel_data(es_id,watch_member_id,imei,live_id,num,flag,region_id,create_time) VALUES(?,?,?,?,?,?,?,?)";
                for(List<Object[]> temp : lists) {
                    System.out.println("执行开始---------》 条数：" + temp.size());
                    TimeInterval timeInterval = DateUtil.timer();
                    try {
                        jdbcTemplate.batchUpdate(sql, temp);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("-------------------   结束    ------------------");
            });
            return hits.length;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }*/


    /**
     * List集合拆分
     *
     * @param list  原始数据
     * @param count 每个list的元素数量
     * @param <T>
     * @return 拆分得到的list集合
     */
    public static <T> List<List<T>> splitListByCount(List<T> list, int count) {
        List<List<T>> listAll = new ArrayList<>();
        int size = list.size();
        if (size > count) {
            int absInt = Math.abs(size / count);
            if (size - absInt * count > 0) {
                listAll.add(list.subList(absInt * count, size));
            }
            for (int i = 1; i < absInt + 1; i++) {
                listAll.add(list.subList((i - 1) * count, i * count));
            }
        } else {
            listAll.add(list);
        }
        return listAll;
    }


    /**
     * 按指定字段去重
     */
    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    public static Map<String,Object> findWatchUserOne(RestHighLevelClient restClient, Long watchMemberId) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.termQuery("watchMemberId", watchMemberId));
        SearchHit[] hits;
        SearchRequest request = new SearchRequest("live_dept_panel");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);//查询参数
        sourceBuilder.size(1);
        request.source(sourceBuilder);
        try {
            hits = restClient.search(request, RequestOptions.DEFAULT).getHits().getHits();
            for(SearchHit hit : hits) {
                Map<String,Object> map = hit.getSourceAsMap();
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/fixData")
    public String fixData()  {
        String sql = "select * from live_attention_temp";
        List<Map<String, Object>> data = jdbcTemplate.queryForList(sql);
        String update = "update live_attention_temp  set region_id = ?, region_name = ?, branch_id = ?,branch_name = ?, area_id = ?, area_name = ?,shop_id = ?,shop_name =  ? where id = ?";
        RestHighLevelClient restHighLevelClient = EsConfig.getEsInstance();
        for(Map<String,Object> map :data) {
            Long userId = (Long) map.get("user_id");
            Long id = (Long) map.get("id");
            Map<String,Object> esData = findWatchUserOne(restHighLevelClient, userId);
            if(null == esData) continue;
            Integer regionId = (Integer) esData.get("regionId");
            String regionName = (String) esData.get("regionName");

            Integer branchId = (Integer) esData.get("branchId");
            String branchName = (String) esData.get("branchName");

            Integer areaId = (Integer) esData.get("areaId");
            String areaName = (String) esData.get("areaName");

            Integer shopId = (Integer) esData.get("shopId");
            String shopName = (String) esData.get("shopName");

            //根据userId更新数据
            jdbcTemplate.update(update, new Object[]{regionId,regionName,branchId,branchName,areaId,areaName,shopId,shopName, id});
        }
        System.out.println(data.size());
        return "";
    }

}
